/**
    ******************************************************************************
    * 函数名称：DMA_Config
    * 功能描述：配置DMA2通道5，用于内存到外设或外设到内存的数据传输
    * 输入参数：
    *           Array1 - 外设地址（源或目标地址）
    *           Array2 - 内存地址（源或目标地址）
    *           Size   - 要传输的数据量（单位：半字，16位）
    * 返回值  ：无
    * 详细说明：
    *   1. 初始化DMA2通道5，配置为外设到内存的传输模式
    *   2. 使用循环模式，传输完成后自动重新开始
    *   3. 外设地址固定，内存地址递增
    *   4. 数据传输单位为半字（16位）
    *   5. 使能DMA通道
    * 
    * 硬件要求：
    *   1. 需要DMA2外设支持
    *   2. 使用通道5（根据具体硬件连接）
    * 
    * 调用示例：
    *   DMA_Config((u32)&ADC1->DR, (u32)ADC_Value, 100);
    ******************************************************************************
**/
#include "DMA_Config.h"

u16 DMA_Size;  // 全局变量，用于存储DMA传输数据量

void DMA_Config(u32 Array1, u32 Array2, u16 Size)
{
    DMA_Size = Size;  // 保存传输数据量供后续使用

    // 使能DMA2时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

    // 定义DMA初始化结构体
    DMA_InitTypeDef DMA_InitStructure;

    // 复位DMA2通道5配置
    DMA_DeInit(DMA2_Channel5);
    
    // 配置DMA初始化参数
    DMA_InitStructure.DMA_PeripheralBaseAddr = Array1;  // 外设基地址
    DMA_InitStructure.DMA_MemoryBaseAddr = Array2;      // 内存基地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 传输方向：外设为源
    DMA_InitStructure.DMA_BufferSize = Size;           // 传输数据量
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不递增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         // 内存地址递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 外设数据宽度：16位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         // 内存数据宽度：16位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;    // 循环模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High; // 高优先级
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;       // 禁用内存到内存模式
    
    // 初始化DMA通道
    DMA_Init(DMA2_Channel5, &DMA_InitStructure);

    // 使能DMA通道
    DMA_Cmd(DMA2_Channel5, ENABLE);
}

/**
    ******************************************************************************
    * 函数名称：DMA_TransFer
    * 功能描述：启动DMA传输并等待传输完成
    * 输入参数：无
    * 返回值  ：无
    * 详细说明：
    *   1. 先禁用DMA通道
    *   2. 设置要传输的数据量
    *   3. 重新使能DMA通道
    *   4. 等待传输完成标志置位
    *   5. 清除传输完成标志
    * 
    * 硬件要求：
    *   1. 必须先调用DMA_Config进行初始化配置
    * 
    * 调用示例：
    *   DMA_TransFer();
    ******************************************************************************
**/
void DMA_TransFer(void)
{
    // 禁用DMA通道以进行配置
    DMA_Cmd(DMA2_Channel5, DISABLE);
    
    // 设置要传输的数据量（使用之前保存的DMA_Size）
    DMA_SetCurrDataCounter(DMA2_Channel5, DMA_Size);
    
    // 重新使能DMA通道开始传输
    DMA_Cmd(DMA2_Channel5, ENABLE);

    // 等待传输完成标志置位
    while(!DMA_GetFlagStatus(DMA2_FLAG_TC5));
    
    // 清除传输完成标志
    DMA_ClearFlag(DMA2_FLAG_TC5);
}
